package com.zhou.hot.update;

/**
 * Created by zhouyongjun on 2020/4/15
 */

import com.sun.tools.attach.VirtualMachine;
import com.zhou.hot.util.HotResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.util.Scanner;
import java.util.regex.Pattern;


public class HotUpdate
{
    public static HotUpdateConfig config;
    public static final String AGENT_JAR_PATH = "E:\\gitee\\public\\hot.update\\hot_update\\HotLoadAgent.jar";
    public static final String PID_FILE = "../bin/pid.RedAlert";
    public final static Logger logger = LoggerFactory.getLogger("hot.update");
    public static Pattern numPattern = Pattern.compile("^[-\\+]?[\\d]*$");
    public static void main(String[] args) throws IOException {
        String pid = null;
        if(args != null && args.length > 0)
        {
            pid = args[0];
        }
        if(pid == null || pid.isEmpty())
        {
            Scanner sc = null;
            try {
                sc = new Scanner(System.in);
                logger.info("输入进程id");
                while (true) {
                    pid = sc.nextLine();
                    if (numPattern.matcher(pid).matches()) break;
                    logger.info("输入错误,请重新输入!");
                }
            } catch (Exception e) {
                logger.error("",e);
            }finally {
                sc.close();
            }
        }
        logger.info("进程ID:"+pid);
        hotLocal(pid);
    }
    public static void init()
    {
        try {
            config = new HotUpdateConfig();
            config.load();
        } catch (Exception e) {
            logger.error("",e);
        }
    }

    /**
     *
     * @return
     */
    public static HotResult hotLocalSelf()
    {
        int pid = getSelfProcessID();
        HotResult result =  hotLocal(String.valueOf(pid));
        logger.info("hot update result : isSucc="+result.isSucc()+",msg=" + result.getMsg());
        return result;
    }

    public static HotResult hotLocal(String pid) {
        VirtualMachine vm = null;
        try {
            init();
            if (pid == null || pid.isEmpty()) pid = config.getPidFromFile();
            if (pid == null || pid.isEmpty())
            {
                return HotResult.RESULT_FAIL;
            }
            logger.info("hot update 热更新 进程："+pid+" 开始...");
            logger.info("hot update 热更新 Agent jar: "+config.getHotLoadAgentJar());
                vm = VirtualMachine.attach(pid);
                vm.loadAgent(config.getHotLoadAgentJar());
                return HotResult.RESULT_SUCC;
        } catch (Exception e) {
            logger.error("hot update VirtualMachine loadAgent 失败",e);
            return HotResult.RESULT_FAIL;
        } finally {
            try {
                logger.info("hot update 热更新 进程："+pid+" 结束...");
                if (vm != null ) vm.detach();
            } catch (Exception e) {
               logger.error("hot update VirtualMachine detach 失败",e);
            }
        }

    }

    /*public static boolean confirmCMD()
    {
        while (true)
        {
            String input = sc.nextLine();
            if (input.equals("yes"))
                return true;
            if ((input.equals("no")) || (input.equals("quit"))) {
                return false;
            }
            logger.info("未知命令,请重新输入[yes/no]");
        }
    }*/

    /**
     * 获取本身进程ID
     * @return
     */
    public static int getSelfProcessID()
    {
        //运行管理
        int id = Integer.parseInt(ManagementFactory.getRuntimeMXBean().getName().split("@")[0]);
        return id;
    }
}